import * as d3 from "d3";
import Minimap from "./minimap";

const CARD_WIDTH = 260;
function generateData(height: number, nodeNum: number) {
  if (height <= 0) return null;
  if (height === 1) return { text: "leaf", h: 40 + Math.random() * 500 + 40, expanded: true };
  const result: { [key: string]: any } = { text: "node", h: 40 + Math.random() * 500 + 40, expanded: true };
  result.children = new Array(Math.ceil(Math.random() * nodeNum));
  for (let i = 0; i < result.children.length; i++) {
    result.children[i] = generateData(height - 1, nodeNum);
  }
  return result;
}

const svg = d3
  .select("#container")
  .append("svg")
  .attr("width", "100%")
  .attr("height", "100%")

const root = d3.hierarchy(generateData(6, 2));

function calcTreeHeight(root: any): number {
  if (!root.children) return root.data.treeHeight = root.data.h;
  let total = 0;
  if (root.children) {
    for (let i = 0; i < root.children.length; i++) {
      total += calcTreeHeight(root.children[i]);
    }
  }
  root.data.treeHeight = Math.max(root.data.h, total);
  return root.data.treeHeight;
}

calcTreeHeight(root);

// 计算xy
const queue = [];
queue.push(root);
while (queue.length) {
  let n = queue.length;
  let preY = 0;
  let preH = 0;
  while (n--) {
    const node = queue.shift();
    node.x = node.depth * (CARD_WIDTH + 100);
    node.y = Math.max(preY + preH, node.parent?.y ?? 0);
    preY = node.y;
    preH = node.data.treeHeight;

    if (node.children) {
      queue.push(...node.children);
    }
    console.log(node.x, node.y);
  }
}
// 内部容器
const view = svg.append("g");

// 渲染卡片
root.each((d) => {
  renderCard(view, d);
});

// 渲染箭头
root.links().forEach((item) => {
  const half = (item.target.x + item.source.x + CARD_WIDTH) / 2;

  const path = d3.path();
  path.moveTo(item.source.x + CARD_WIDTH, item.source.y + 20);
  path.lineTo(half, item.source.y + 20);
  path.lineTo(half, item.target.y + 20);
  path.lineTo(item.target.x - 12, item.target.y + 20);

  const triangle = d3.path();
  triangle.moveTo(item.target.x, item.target.y + 20);
  triangle.lineTo(item.target.x - 14, item.target.y + 5 + 20);
  triangle.lineTo(item.target.x - 14, item.target.y - 5 + 20);
  triangle.closePath();

  view.append("path")
    .attr("d", path.toString())
    .attr("stroke", "blue")
    .attr("stroke-width", 4)
    .attr("fill", "transparent");

  view.append("path")
    .attr("d", triangle.toString())
    .attr("stroke", "blue")
    .attr("stroke-width", 2)
    .attr("fill", "blue");
});


const minimap = new Minimap(svg);
minimap.draw({ backgroundFill: "#e2e2e2" });

function renderCard(view: any, d: any) {
  const card = view.append("g").attr("transform", `translate(${d.x}, ${d.y})`);

  card
    .append("rect")
    .attr("width", CARD_WIDTH)
    .attr("height", d.data.h - 40)
    .attr("fill", "#fff");

  card
    .append("line")
    .attr("stroke", "#ddd")
    .attr("x1", 0)
    .attr("y1", 40)
    .attr("x2", CARD_WIDTH)
    .attr("y2", 40);
}
